package com.bangcommunity.bbframe.fdfs;

import org.csource.common.NameValuePair;
import org.csource.fastdfs.FileInfo;

import java.io.InputStream;
import java.io.OutputStream;

public interface FdfsClient {

    String SPLIT_GROUP_NAME_AND_FILENAME_SEPERATOR = "/";

    /**
     * 根据流执行上传。有输入流,但不知道文件总大小的情况下使用。 上传先读入到512k的内存块中,上传到服务器,然后后续的字节追加到第一次上传的块上,性能较低,有oom可能
     * 建议能获取fileSize情况下不要调用该方法
     * 
     * @param inputStream
     * @param group
     * @param ext
     * @param canAppender
     *            上传后的文件是否可以追加内容
     * @return
     * @throws Exception
     */
    FdfsBlockResult<String> upload(InputStream inputStream, String group, String ext, boolean canAppender)
            throws Exception;

    /**
     * 根据流执行上传。指定文件大小
     * 
     * @param inputStream
     * @param fileSize
     * @param group
     * @param ext
     * @param canAppender
     * @return
     * @throws Exception
     */
    String upload(InputStream inputStream, long fileSize, String group, String ext, boolean canAppender)
            throws Exception;

    /**
     * 根据字节数组上传文件
     * 
     * @param fileBuff
     * @param group
     * @param ext
     * @param canAppender
     * @return
     * @throws Exception
     */
    String upload(byte[] fileBuff, String group, String ext, boolean canAppender) throws Exception;

    /**
     * 根据字节数组上传。指定需要上传的字节数组的索引范围
     * 
     * @param fileBuff
     * @param offset
     * @param length
     * @param group
     * @param ext
     * @param canAppender
     * @return
     * @throws Exception
     */
    String upload(byte[] fileBuff, int offset, int length, String group, String ext, boolean canAppender)
            throws Exception;

    /**
     * 根据字节数组追加上传文件。
     * 
     * @param fullFileId
     * @param fileBuff
     * @return
     * @throws Exception
     */
    boolean append(String fullFileId, byte[] fileBuff) throws Exception;

    /**
     * 根据字节数组追加上传文件.指定需要上传的字节数组的索引范围
     * 
     * @param fullFileId
     * @param fileBuff
     * @param offset
     * @param length
     * @return
     * @throws Exception
     */
    boolean append(String fullFileId, byte[] fileBuff, int offset, int length) throws Exception;

    /**
     * 根据流追加上传文件。文件大小未知
     * 
     * @param fullFileId
     * @param inputStream
     * @return
     * @throws Exception
     */
    FdfsBlockResult<Boolean> append(String fullFileId, InputStream inputStream) throws Exception;

    /**
     * 根据流追加上传文件。文件大小已知
     * 
     * @param fullFileId
     * @param inputStream
     * @param fileSize
     * @return
     * @throws Exception
     */
    boolean append(String fullFileId, InputStream inputStream, long fileSize) throws Exception;

    /**
     * 将文件下载到内存数组
     * 
     * @param fullFileId
     * @return
     * @throws Exception
     */
    byte[] download(String fullFileId) throws Exception;

    /**
     * 将文件下载到输出流
     * 
     * @param fullFileId
     * @param outputStream
     * @return
     * @throws Exception
     */
    boolean download(String fullFileId, OutputStream outputStream) throws Exception;

    /**
     * 指定文件的字节范围,下载到内存数组
     * 
     * @param fullFileId
     * @param fileOffset
     * @param downloadBytes
     * @return
     * @throws Exception
     */
    byte[] download(String fullFileId, long fileOffset, long downloadBytes) throws Exception;

    /**
     * 指定文件的字节范围,下载到输出流
     * 
     * @param fullFileId
     * @param fileOffset
     * @param downloadBytes
     * @param outputStream
     * @return
     * @throws Exception
     */
    boolean download(String fullFileId, long fileOffset, long downloadBytes, OutputStream outputStream)
            throws Exception;

    FdfsSourceInputStream getFdfsSourceInputStream(String fullFileId, long fileOffset,
            long downloadBytes) throws Exception;

    /**
     * 使用字节数组替换文件
     * 
     * @param fullFileId
     * @param fileBuff
     * @return
     * @throws Exception
     */
    boolean modify(String fullFileId, byte[] fileBuff) throws Exception;

    /**
     * 使用输入流替换文件。流大小未知
     * 
     * @param fullFileId
     * @param inputStream
     * @return
     * @throws Exception
     */
    FdfsBlockResult<Boolean> modify(String fullFileId, InputStream inputStream) throws Exception;

    /**
     * 使用输入流替换文件。流大小已知
     * 
     * @param fullFileId
     * @param inputStream
     * @param fileSize
     * @return
     * @throws Exception
     */
    boolean modify(String fullFileId, InputStream inputStream, long fileSize) throws Exception;

    /**
     * 使用指定范围的字节数组 指定文件位置开始替换
     * 
     * @param fullFileId
     * @param fileOffset
     * @param fileBuff
     * @param offset
     * @param length
     * @return
     * @throws Exception
     */
    boolean modify(String fullFileId, long fileOffset, byte[] fileBuff, int offset, int length) throws Exception;

    /**
     * 使用字节数组 指定文件位置开始替换
     * 
     * @param fullFileId
     * @param fileOffset
     * @param fileBuff
     * @return
     * @throws Exception
     */
    boolean modify(String fullFileId, long fileOffset, byte[] fileBuff) throws Exception;

    /**
     * 使用流 指定文件位置开始替换
     * 
     * @param fullFileId
     * @param fileOffset
     * @param inputStream
     * @param fileSize
     * @return
     * @throws Exception
     */
    boolean modify(String fullFileId, long fileOffset, InputStream inputStream, long fileSize) throws Exception;

    /**
     * 使用流。指定文件位置开始替换
     * 
     * @param fullFileId
     * @param fileOffset
     * @param inputStream
     * @return
     * @throws Exception
     */
    FdfsBlockResult<Boolean> modify(String fullFileId, long fileOffset, InputStream inputStream) throws Exception;

    /**
     * 获取文件信息
     * 
     * @param fullFileId
     * @return
     * @throws Exception
     */
    FileInfo getFileInfo(String fullFileId) throws Exception;

    /**
     * 设置元数据信息。 建议不要使用。元数据较小浪费存储空间
     * 
     * @param fullFileId
     * @param metaList
     * @param isMerge
     *            true 将本次的元数据和已有的元数据合并,如果已经存在则修改,不存在则新建。 false 使用这次的元数据覆盖已有元数据
     * @return
     * @throws Exception
     */
    boolean setMetadata(String fullFileId, NameValuePair[] metaList, boolean isMerge) throws Exception;

    /**
     * 获取元数据信息
     * 
     * @param fullFileId
     * @return
     * @throws Exception
     */
    NameValuePair[] getMetadata(String fullFileId) throws Exception;

    /**
     * 删除文件
     * 
     * @param fileId
     * @return
     * @throws Exception
     */
    boolean delete(String fileId) throws Exception;

    /**
     * 关闭客户端
     */
    void close();

}
